package org.farng.mp3.object;

import org.farng.mp3.TagConstant;

import java.util.HashMap;
import java.util.Iterator;
import java.util.TreeSet;


/**
 * <p>
 * Title:
 * </p>
 * 
 * <p>
 * Description:
 * </p>
 * 
 * <p>
 * Copyright: Copyright (c) 2002
 * </p>
 * 
 * <p>
 * Company:
 * </p>
 *
 * @author Eric Farng
 * @version $Revision: 1.6 $
 */
public class ObjectNumberHashMap extends ObjectNumberFixedLength implements ObjectHashMapInterface {
    /** DOCUMENT ME! */
    public static final String GENRE = "Genre";

    /** DOCUMENT ME! */
    public static final String TEXT_ENCODING = "Text Encoding";

    /** DOCUMENT ME! */
    public static final String INTERPOLATION_METHOD = "Interpolation Method";

    /** DOCUMENT ME! */
    public static final String ID3V2_FRAME_DESCRIPTION = "ID3v2 Frame Description";

    /** DOCUMENT ME! */
    public static final String PICTURE_TYPE = "Picture Type";

    /** DOCUMENT ME! */
    public static final String TYPE_OF_EVENT = "Type Of Event";

    /** DOCUMENT ME! */
    public static final String TIME_STAMP_FORMAT = "Time Stamp Format";

    /** DOCUMENT ME! */
    public static final String TYPE_OF_CHANNEL = "Type Of Channel";

    /** DOCUMENT ME! */
    public static final String RECIEVED_AS = "Recieved As";

    /** DOCUMENT ME! */
    private HashMap idToString = null;

    /** DOCUMENT ME! */
    private HashMap stringToId = null;

    /** DOCUMENT ME! */
    private boolean hasEmptyValue = false;

    /**
     * Creates a new ObjectNumberHashMap object.
     *
     * @param identifier DOCUMENT ME!
     * @param size DOCUMENT ME!
     *
     * @throws IllegalArgumentException DOCUMENT ME!
     */
    public ObjectNumberHashMap(String identifier, int size) {
        super(identifier, size);

        if (identifier.equals(ObjectNumberHashMap.GENRE)) {
            stringToId    = TagConstant.genreStringToId;
            idToString    = TagConstant.genreIdToString;
            hasEmptyValue = true;
        } else if (identifier.equals(ObjectNumberHashMap.TEXT_ENCODING)) {
            stringToId = TagConstant.textEncodingStringToId;
            idToString = TagConstant.textEncodingIdToString;
        } else if (identifier.equals(ObjectNumberHashMap.INTERPOLATION_METHOD)) {
            stringToId = TagConstant.interpolationMethodStringToId;
            idToString = TagConstant.interpolationMethodIdToString;
        } else if (identifier.equals(ObjectNumberHashMap.ID3V2_FRAME_DESCRIPTION)) {
            stringToId = TagConstant.id3v2_4FrameStringToId;
            idToString = TagConstant.id3v2_4FrameIdToString;
        } else if (identifier.equals(ObjectNumberHashMap.PICTURE_TYPE)) {
            stringToId = TagConstant.pictureTypeStringToId;
            idToString = TagConstant.pictureTypeIdToString;
        } else if (identifier.equals(ObjectNumberHashMap.TYPE_OF_EVENT)) {
            stringToId = TagConstant.typeOfEventStringToId;
            idToString = TagConstant.typeOfEventIdToString;
        } else if (identifier.equals(ObjectNumberHashMap.TIME_STAMP_FORMAT)) {
            stringToId = TagConstant.timeStampFormatStringToId;
            idToString = TagConstant.timeStampFormatIdToString;
        } else if (identifier.equals(ObjectNumberHashMap.TYPE_OF_CHANNEL)) {
            stringToId = TagConstant.typeOfChannelStringToId;
            idToString = TagConstant.typeOfChannelIdToString;
        } else if (identifier.equals(ObjectNumberHashMap.RECIEVED_AS)) {
            stringToId = TagConstant.recievedAsStringToId;
            idToString = TagConstant.recievedAsIdToString;
        } else {
            throw new IllegalArgumentException("Hashmap identifier not defined in this class: " + identifier);
        }
    }

    public ObjectNumberHashMap(ObjectNumberHashMap copyObject) {
        super(copyObject);

        this.hasEmptyValue = copyObject.hasEmptyValue;

        // we dont' need to clone/copy the maps here because they are static
        this.idToString = copyObject.idToString;
        this.stringToId = copyObject.stringToId;
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public HashMap getIdToString() {
        return idToString;
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public HashMap getStringToId() {
        return stringToId;
    }

    /**
     * DOCUMENT ME!
     *
     * @param value DOCUMENT ME!
     */
    public void setValue(Object value) {
        if (value instanceof Byte) {
            this.value = new Long(((Byte) value).byteValue());
        } else if (value instanceof Short) {
            this.value = new Long(((Short) value).shortValue());
        } else if (value instanceof Integer) {
            this.value = new Long(((Integer) value).intValue());
        } else {
            this.value = value;
        }
    }

    /**
     * DOCUMENT ME!
     *
     * @param obj DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public boolean equals(Object obj) {
        if ((obj instanceof ObjectNumberHashMap) == false) {
            return false;
        }

        ObjectNumberHashMap object = (ObjectNumberHashMap) obj;

        if (this.hasEmptyValue != object.hasEmptyValue) {
            return false;
        }

        if (this.idToString == null) {
            if (object.idToString != null) {
                return false;
            }
        } else {
            if (this.idToString.equals(object.idToString) == false) {
                return false;
            }
        }

        if (this.stringToId == null) {
            if (object.stringToId != null) {
                return false;
            }
        } else {
            if (this.stringToId.equals(object.stringToId) == false) {
                return false;
            }
        }

        return super.equals(obj);
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public Iterator iterator() {
        if (idToString == null) {
            return null;
        } else {
            // put them in a treeset first to sort them
            TreeSet treeSet = new TreeSet(idToString.values());

            if (hasEmptyValue) {
                treeSet.add("");
            }

            return treeSet.iterator();
        }
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public String toString() {
        if (value == null) {
            return "";
        } else if (idToString.get(value) == null) {
            return "";
        } else {
            return idToString.get(value).toString();
        }
    }
}